/*
 * teste_open.c (Refer�ncia: plano_teste.doc item 4.2)
 *
 * Verificar se a fun��o open realiza a abertura de tres arquivos.
 *
 * O objetivo deste teste � verificar se a cache de inodes funciona, colocando
 * dois blocos na lista.
 *
 *  Created on: Oct 26, 2009
 *      Author: giovane
 */

#include <fs.h>
#include <pcb.h>

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

PCB pcb;

void logDescriptor(int fd, FILE* output);

int main(){

	int fd1 = open("/teste.txt", "r");

	printf("\nDados do arquivo teste.txt\n");
	if(fd1 != -1){
		logDescriptor(fd1, stdout);
	}
	else{
		printf("Erro ao abrir o arquivo teste1.txt - errno: %d", errno);
	}

	int fd2 = open("/teste2.txt", "r");

	printf("\nDados do arquivo teste2.txt\n");
	if(fd2 != -1){
		logDescriptor(fd2, stdout);
	}
	else{
		printf("Erro ao abrir o arquivo teste2.txt - errno: %d", errno);
	}

	int fd3 = open("/teste3.txt", "r");

	printf("\nDados do arquivo teste3.txt\n");
	if(fd3 != -1){
		logDescriptor(fd3, stdout);
	}
	else{
		printf("Erro ao abrir o arquivo teste3.txt - errno: %d", errno);
	}

	return 0;



}

void logDescriptor(int fd, FILE* output){

	//Imprimindo informa��es do descritor

	fprintf(output,"###### Retorno #######\n");

	fprintf(output,"retorno: %d \n", fd);

	fprintf(output,"errno: %d \n", errno);

	fprintf(output,"###### Descritor ######\n");

	fprintf(output,"nr descritor: %d \n", fd);

	fprintf(output,"usado: %s \n", pcb.descriptors[fd].usado ? "SIM" : "NAO");

	fprintf(output,"ptr_taa: %u \n", pcb.descriptors[fd].ptr_fentry);

	fprintf(output,"endereco_buffer: %u \n", pcb.descriptors[fd].buffer);

	fprintf(output,"mode: %d \n", pcb.descriptors[fd].mode);

	fprintf(output,"posicao_arquivo: %d \n", pcb.descriptors[fd].fpos);

	fprintf(output,"nr_bloco_buffer: %d \n", pcb.descriptors[fd].buffer_block);

	fprintf(output,"changed: %d \n", pcb.descriptors[fd].buffer_changed);

	fprintf(output,"##### TAA #####\n");

	fprintf(output,"fcount: %d \n", pcb.descriptors[fd].ptr_fentry->fcount);

	fprintf(output,"inode: %d \n", pcb.descriptors[fd].ptr_fentry->inode_num);

	fprintf(output,"##### inode #####\n");

	fprintf(output,"tipo_arquivo: %d \n", pcb.descriptors[fd].ptr_fentry->f_inode.tipo_arquivo);

	fprintf(output,"tamanho: %d \n", pcb.descriptors[fd].ptr_fentry->f_inode.f_size);



}

typedef struct{
  char name[32];   //nome de elemento do diret�rio.
  int f_inode;     //n�mero do i-node do arquivo.
} d_name;

int carrega_bloco_no_buffer(int end_bloco, void* ptr_buffer){

	int i = 0;

	inode* vet_inode = (inode*) ptr_buffer;

	switch(end_bloco){
		case 0:
			//Carrego o super-bloco
			break;
		case 1:
			//Primeiro bloco de inodes

			inode inode0;

			inode0.direct_blocks[0] = 600;

			for(i = 1; i < 10; i++){
				inode0.direct_blocks[i] = 0;
			}

			inode0.single_indirection = 0;
			inode0.double_indirection = 0;
			inode0.triple_indirection = 0;

			inode0.f_owner = 1;

			inode0.f_group = 1;

			inode0.f_access_date = 0;
			inode0.f_change_date = 0;
			inode0.f_create_date = 0;

			inode0.f_permissions = OWNER_WRITE_PERMISSION | OWNER_READ_PERMISSION | OWNER_EXECUTE_PERMISSION;

			inode0.tipo_arquivo = 'd';

			inode0.f_size = 108;

			inode inode1;

			inode1.direct_blocks[0] = 604;

			for(i = 1; i < 10; i++){
				inode1.direct_blocks[i] = 0;
			}

			inode1.single_indirection = 0;
			inode1.double_indirection = 0;
			inode1.triple_indirection = 0;

			inode1.f_owner = 1;

			inode1.f_group = 1;

			inode1.f_access_date = 0;
			inode1.f_change_date = 0;
			inode1.f_create_date = 0;

			inode1.f_permissions = OWNER_WRITE_PERMISSION | OWNER_READ_PERMISSION | OWNER_EXECUTE_PERMISSION;

			inode1.tipo_arquivo = 'r';

			inode1.f_size = 1024;

			inode inode2;

			inode2.direct_blocks[0] = 608;

			for(i = 1; i < 10; i++){
				inode2.direct_blocks[i] = 0;
			}

			inode2.single_indirection = 0;
			inode2.double_indirection = 0;
			inode2.triple_indirection = 0;

			inode2.f_owner = 1;

			inode2.f_group = 1;

			inode2.f_access_date = 0;
			inode2.f_change_date = 0;
			inode2.f_create_date = 0;

			inode2.f_permissions = OWNER_WRITE_PERMISSION | OWNER_READ_PERMISSION | OWNER_EXECUTE_PERMISSION;

			inode2.tipo_arquivo = 'r';

			inode2.f_size = 1024;

			inode inode3;

			inode3.direct_blocks[0] = 612;

			for(i = 1; i < 10; i++){
				inode3.direct_blocks[i] = 0;
			}

			inode3.single_indirection = 0;
			inode3.double_indirection = 0;
			inode3.triple_indirection = 0;

			inode3.f_owner = 1;

			inode3.f_group = 1;

			inode3.f_access_date = 0;
			inode3.f_change_date = 0;
			inode3.f_create_date = 0;

			inode3.f_permissions = OWNER_WRITE_PERMISSION | OWNER_READ_PERMISSION | OWNER_EXECUTE_PERMISSION;

			inode3.tipo_arquivo = 'r';

			inode3.f_size = 1024;

			memcpy(&(vet_inode[0]), &inode0, sizeof(inode));

			memcpy(&(vet_inode[1]), &inode1, sizeof(inode));

			memcpy(&(vet_inode[2]), &inode2, sizeof(inode));

			memcpy(&(vet_inode[3]), &inode3, sizeof(inode));

			break;

		case 600:

			d_name diretorios[5];

			strcpy(diretorios[0].name,".");
			diretorios[0].f_inode = 0;

			strcpy(diretorios[1].name,"..");
			diretorios[1].f_inode = 0;

			strcpy(diretorios[2].name, "teste.txt");
			diretorios[2].f_inode = 1;

			strcpy(diretorios[3].name, "teste2.txt");
			diretorios[3].f_inode = 2;

			strcpy(diretorios[4].name, "teste3.txt");
			diretorios[4].f_inode = 3;

			memcpy(ptr_buffer, diretorios, 5*sizeof(d_name));

		break;

		default:
			memset(ptr_buffer, 5, BLOCK_SIZE);
	}

}

int alloc_taa_entry(fentry** entry, ftable* table, int inode){

	*entry = (fentry*) malloc(sizeof(fentry));

	//TODO inserir entry na tabela
	memset(*entry, 0, sizeof(fentry));

	return 0;
}

int get_taa_entry(fentry** entry, ftable* table, int inode){
	return -1;
}

int dealloc_taa_entry(fentry* entry, ftable* table){

	//Remove da lista de table o entry
	//TODO

	//Libera mem�ria
	free(entry);

	return 0;
}

